package com.uzai.console.service.reportpanel.impl;

import cn.hutool.core.date.DateTime;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.uzai.common.dto.base.BizLog;
import com.uzai.common.enums.DeviceTypeEnum;
import com.uzai.common.enums.LogBizTypeEnum;
import com.uzai.common.exception.BusinessException;
import com.uzai.console.annotation.DataPanel;
import com.uzai.console.common.utils.DateUtil;
import com.uzai.console.dto.remoteapi.DataPanelRemoteQuery;
import com.uzai.console.dto.reportpanel.DataPanelOptDto;
import com.uzai.console.dto.reportpanel.DataPanelQueryDto;
import com.uzai.console.dto.wechatprivate.friendrequest.FriendRequestQuery;
import com.uzai.console.entity.ReportPanel;
import com.uzai.console.enums.ReportBanelFansValueShowFieldEnum;
import com.uzai.console.enums.ReportPanelTypeEnum;
import com.uzai.console.mapper.DataPanelMapper;
import com.uzai.console.service.reportpanel.BaseDataPanelService;
import com.uzai.console.service.reportpanel.DataPanelService;
import com.uzai.console.service.wechatprivate.FriendRequestService;
import com.uzai.console.vo.device.DeviceInfoVo;
import com.uzai.console.vo.reportpanel.DataPanelFriendRequestVo;
import com.uzai.console.vo.reportpanel.DataPanelVo;
import com.uzai.console.vo.wechatprivate.friendrequest.FriendRequestCountItemVo;
import com.uzai.console.vo.wechatprivate.friendrequest.FriendRequestCountVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author mingyang.chen create in 2023/3/29 11:30
 */
@DataPanel
@Slf4j

public class FriendRequestDataPanelServiceImpl extends BaseDataPanelService implements DataPanelService {

    @Autowired
    private DataPanelMapper dataPanelMapper;

    @Autowired
    private FriendRequestService friendRequestService;

    @Override
    public ReportPanelTypeEnum getDataPanelType() {
        return ReportPanelTypeEnum.FRIEND_REQUEST;
    }

    @Override
    public Class<? extends DataPanelVo> childDataPanelVoClass() {
        return DataPanelFriendRequestVo.class;
    }

    @Override
    public Page<? extends DataPanelVo> pageDataPanel(DataPanelQueryDto queryDto) {

        //判断查询条件
        if (Objects.isNull(queryDto.getMerId()) || Objects.isNull(queryDto.getType())) {
            throw new BusinessException("好友请求数据面板分页参数错误");
        }
        // 查询到记录
        Page<ReportPanel> page = new Page<>(queryDto.getCurrent(), queryDto.getSize());
        queryDto.setMerId(queryDto.getMerId());
        queryDto.setDeviceType(queryDto.getDeviceType());

        Page<ReportPanel> pageResult = dataPanelMapper.selectPageByCondition(page, queryDto);

        List<DataPanelFriendRequestVo> reportPanelVoList = new ArrayList<>();
        for (ReportPanel reportPanel : pageResult.getRecords()) {
            DataPanelFriendRequestVo convert = (DataPanelFriendRequestVo) convert(reportPanel);
            reportPanelVoList.add(convert);
        }
        Page<DataPanelFriendRequestVo> result = new Page<>(pageResult.getCurrent(), pageResult.getSize(), pageResult.getTotal());
        result.setRecords(reportPanelVoList);
        return result;
    }

    @Override
    public void addDataPanel(DataPanelOptDto panelOptDto) {

        ReportPanel reportPanel = new ReportPanel();
        reportPanel.setId(IdWorker.getId());
        reportPanel.setMerId(panelOptDto.getMerId());
        reportPanel.setType(getDataPanelType().getId());
        reportPanel.setDeviceType(panelOptDto.getDeviceType());
        JSONObject para_data = new JSONObject();
        para_data.put("deviceType", panelOptDto.getDeviceType());
        para_data.put("deviceUniqueIdList", panelOptDto.getDeviceUniqueIdList());
        para_data.put("queryStartTime", panelOptDto.getQueryStartTime());
        para_data.put("scenes", panelOptDto.getScenes());
        reportPanel.setParaData(para_data.toJSONString());
        JSONObject show_data = new JSONObject();
        show_data.put("showFieldList", panelOptDto.getShowFieldList());
        reportPanel.setShowData(show_data.toJSONString());
        reportPanel.setRemark(panelOptDto.getRemark());
        int now = DateUtil.getNowTime();
        reportPanel.setCreateTime(now);
        reportPanel.setUpdateTime(now);

        dataPanelMapper.insertSelective(reportPanel);

        // 打印日志,用于收集新增记录
        log.info(JSONObject.toJSONString(new BizLog(LogBizTypeEnum.CONSOLE_FANS_COUNT_DATA_PANEL.getValue(),
                reportPanel.getMerId(), DeviceTypeEnum.getByKey(reportPanel.getDeviceType()).getId(), null, null, null, "创建数据面板")));
    }

    @Override
    public DataPanelVo convert(ReportPanel reportPanel) {
        DataPanelVo convert = super.convert(reportPanel);
        JSONObject jsonObject_para = JSONObject.parseObject(reportPanel.getParaData());
        JSONArray scenes = jsonObject_para.getJSONArray("scenes");
        if (ObjectUtils.isNotEmpty(scenes)) {
            convert.setScenes(scenes.toJavaList(String.class));
        }
        convert.setQueryEndTime(jsonObject_para.getInteger("queryEndTime"));
        return convert;
    }

    @Override
    public HashMap<String, String> showFieldList() {
        HashMap<String, String> showFieldHashMap = new HashMap<>();

        showFieldHashMap.put(ReportBanelFansValueShowFieldEnum.DEVICENAME.getKey(), ReportBanelFansValueShowFieldEnum.DEVICENAME.getDesc());
        showFieldHashMap.put(ReportBanelFansValueShowFieldEnum.DEVICEREMARK.getKey(), ReportBanelFansValueShowFieldEnum.DEVICEREMARK.getDesc());
        showFieldHashMap.put(ReportBanelFansValueShowFieldEnum.TIMER.getKey(), ReportBanelFansValueShowFieldEnum.TIMER.getDesc());
        return showFieldHashMap;
    }

    @Override
    public Object checkAndBuildRemoteParam(DataPanelRemoteQuery query) {
        ReportPanel dataPanel = query.getDataPanel();

        JSONObject data = JSONObject.parseObject(dataPanel.getParaData());
        Integer queryStartTime = data.getInteger("queryStartTime");
        Integer queryEndTime = data.getInteger("queryEndTime");
        // 没有结束时间
        boolean noHasEndTime = Objects.isNull(queryEndTime) || 0 == queryEndTime;

        if (Objects.nonNull(query.getQueryStartTime()) && query.getQueryStartTime() < queryStartTime) {
            throw new BusinessException("开始时间不能在设置的开始时间之前");
        }

        if (Objects.nonNull(query.getQueryEndTime())
                && !(noHasEndTime)
                && query.getQueryEndTime() > queryEndTime) {
            throw new BusinessException("结束时间不能在设置的结束时间之后");
        }

        // 为空用数据库的
        if (Objects.isNull(query.getQueryStartTime())) {
            query.setQueryStartTime(queryStartTime);
        }
        // 为空用数据库的
        if (Objects.isNull(query.getQueryEndTime())) {
            if (noHasEndTime) {
                queryEndTime = (int) (DateTime.now().getTime() / 1000L);
            }
            query.setQueryEndTime(queryEndTime);
        }
        // Integer queryEndTime = data.getInteger("queryEndTime");

        /*if (Objects.isNull(queryEndTime) || 0 == queryEndTime) {
            queryEndTime = (int) (DateTime.now().getTime() / 1000L);
        }*/
        List<Integer> scenes = ObjectUtils.defaultIfNull(data.getJSONArray("scenes"), new JSONArray()).toJavaList(Integer.class);

        FriendRequestQuery friendRequestQuery = new FriendRequestQuery();

        friendRequestQuery.setReqTimeStart(query.getQueryStartTime());
        friendRequestQuery.setReqTimeEnd(query.getQueryEndTime());
        friendRequestQuery.setMerId(query.getMerId());
        friendRequestQuery.setDeviceType(query.getDeviceType());
        friendRequestQuery.setDeviceUniqueIds(query.getDeviceUniqueIdList());
        friendRequestQuery.setDeviceUniqueIds(query.getDeviceUniqueIdList());
        if (ObjectUtils.isNotEmpty(scenes)) {
            friendRequestQuery.setScenes(scenes);
        }
        return friendRequestQuery;
    }

    @Override
    public Object remoteDataQuery(DataPanelRemoteQuery query) {

        FriendRequestQuery friendRequestQuery = (FriendRequestQuery) this.checkAndBuildRemoteParam(query);

//        boolean needQueryOther = false;
        // 手动分页
//        if (finalDeviceUniqueIdList.size() > query.getSize()) {
//            int startIndex = (query.getCurrent() - 1) * query.getSize(); // 计算起始索引
//            int endIndex = Math.min(startIndex + query.getSize(), finalDeviceUniqueIdList.size());
//            List<Long> pageList = finalDeviceUniqueIdList.subList(startIndex, endIndex);
//
//            friendRequestQuery.setDeviceUniqueIds(pageList);
//            needQueryOther = true;
//        }
//        // 小于数量
//        else {
//            friendRequestQuery.setDeviceUniqueIds(query.getDeviceUniqueIdList());
//        }

        List<FriendRequestCountItemVo> friendRequestCountVos = friendRequestService.countFriendApplyAndPassCount(friendRequestQuery);

        List<DeviceInfoVo> existsDeviceInfoVos = super.listDeviceInfoByIds(query.getMerId(), query.getDeviceType(), friendRequestQuery.getDeviceUniqueIds());
        Map<Long, DeviceInfoVo> existsDeviceMap = existsDeviceInfoVos.stream().collect(Collectors.toMap(DeviceInfoVo::getId, Function.identity()));
        for (FriendRequestCountItemVo item : friendRequestCountVos) {
            if (!existsDeviceMap.containsKey(item.getDeviceUniqueId())) {
                continue;
            }
            DeviceInfoVo deviceInfo = existsDeviceMap.get(item.getDeviceUniqueId());
            item.setDeviceRemark(deviceInfo.getDeviceRemark());
            item.setDeviceName(deviceInfo.getDeviceName());
            item.setOnline(deviceInfo.getOnline());
        }
        FriendRequestCountVo friendRequestCountVo = new FriendRequestCountVo();
        /*if (needQueryOther) {
            // 修改机器人数量为所有查询条件中的所有机器人, 包含已经分页的
            friendRequestQuery.setDeviceUniqueIds(query.getDeviceUniqueIdList());
            Map<Long, Integer> totalledFriendRequestCount = friendRequestService.totalFriendRequestCount(friendRequestQuery);
            int sum = totalledFriendRequestCount.values().stream().mapToInt(Integer::intValue).sum();
            friendRequestCountVo.setTotalCount(sum);
        } else {
            int sum = friendRequestCountVos.stream().mapToInt(FriendRequestCountItemVo::getCount).sum();
            friendRequestCountVo.setTotalCount(sum);
        }*/
        int totalApplyCount = friendRequestCountVos.stream().mapToInt(FriendRequestCountItemVo::getApplyCount).sum();
        int totalPassCount = friendRequestCountVos.stream().mapToInt(FriendRequestCountItemVo::getPassCount).sum();

        friendRequestCountVo.setTotalApplyCount(totalApplyCount);
        friendRequestCountVo.setTotalPassCount(totalPassCount);
        int size = friendRequestQuery.getDeviceUniqueIds().size();
        friendRequestCountVo.setTotalDeviceCount(size);

        Page<FriendRequestCountItemVo> result = new Page<>(query.getCurrent(), query.getSize(), size);
        result.setRecords(friendRequestCountVos);
        friendRequestCountVo.setPages(result);

        return friendRequestCountVo;
    }
}
